package com.ruicar.afs.cloud.afscase.approvetask.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.condition.ApproveCondition;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkProcessScheduleInfo;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPool;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPoolHistory;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolHistoryService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.approvetask.vo.ApproveSubmitVO;
import com.ruicar.afs.cloud.afscase.approvetask.vo.ChangeAssetsViewVo;
import com.ruicar.afs.cloud.afscase.approvetask.vo.ChangeAssetsVo;
import com.ruicar.afs.cloud.afscase.approvetask.vo.WorkflowCancelVO;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseRedundantInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseRedundantInfoService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveInformInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.afscase.processor.service.ChangeAssetsWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalTaskSubmitVO;
import com.ruicar.afs.cloud.afscase.remind.entity.CaseRemindDetail;
import com.ruicar.afs.cloud.afscase.remind.service.RemindService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @description: 资产变更
 * @author jiaqi.guo
 * @created 2020/7/28 19:48
 * @version 1.0
 */
@Slf4j
@RestController
@AllArgsConstructor
@Api("审核任务")
@RequestMapping("/changeAssets")
public class ChangeAssetsTaskController {

    private WorkTaskPoolService workTaskPoolService;
    private WorkProcessScheduleInfoService workProcessScheduleInfoService;
    private ChangeAssetsWorkflowService workflowService;
    private CaseBaseInfoService caseBaseInfoService;
    private ApproveInformInfoService approveInformInfoService;
    private CaseApproveRecordService caseApproveRecordService;
    private RemindService remindService;
    private CaseRedundantInfoService redundantInfoService;
    private WorkTaskPoolHistoryService workTaskPoolHistoryService;

    @GetMapping("/queryApprove")
    @ApiOperation("资产变更暂存审批意见查询")
    public IResponse queryApprove(@ModelAttribute ApproveCondition approveCondition) {
        WorkTaskPool workTaskPool = workTaskPoolService.getOne(
                Wrappers.<WorkTaskPool>lambdaQuery()
                        .eq(WorkTaskPool::getApplyNo, approveCondition.getApplyNo())
                        .eq(WorkTaskPool::getStageId, approveCondition.getStageId())
        );
        if (Objects.nonNull(workTaskPool)) {
            String remainDataStr = workTaskPool.getRemainData();
            CaseApproveRecord record = new CaseApproveRecord();
            record.setApplyNo(approveCondition.getApplyNo());
            record.setStageId(approveCondition.getStageId());
            if (StringUtils.isNotBlank(remainDataStr)) {
                JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                    record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(), CaseApproveRecord.class);
                }
            }
            return IResponse.success(record);
        } else {
            return IResponse.success("");
        }
    }

    @GetMapping("/querySubmitApprove")
    @ApiOperation("复议申请已提交意见查询")
    public IResponse querySubmitApprove(@ModelAttribute ApproveCondition approveCondition) {
                //查询组长已提交至部长的意见，以及部长退回的最新意见
                List<WorkTaskPoolHistory> workTaskPoolHistoryList = workTaskPoolHistoryService.list(
                        Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                                .eq(WorkTaskPoolHistory::getApplyNo,approveCondition.getApplyNo())
                                .eq(WorkTaskPoolHistory::getStageId,approveCondition.getStageId())
                                .orderByDesc(WorkTaskPoolHistory::getCreateTime)
                );
                if (ObjectUtils.isNotEmpty(workTaskPoolHistoryList)) {
                    WorkTaskPoolHistory workTaskPoolHistory = workTaskPoolHistoryList.get(0);
                    CaseApproveRecord record = new CaseApproveRecord();
                    String remainDataStr = workTaskPoolHistory.getRemainData();
                    if (StringUtils.isNotBlank(remainDataStr)) {
                        JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                        if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                            record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(), CaseApproveRecord.class);
                        }
                    }
                    return IResponse.success(record);
                }
                    return IResponse.success("");
    }

    @GetMapping("/queryAllApprove")
    @ApiOperation("复议申请已提交审批建议查询")
    public IResponse<List<CaseApproveRecord>> queryAllApprove(@ModelAttribute ApproveCondition approveCondition) {
        List<CaseApproveRecord> recordList = new ArrayList<>();
        CaseApproveRecord record = new CaseApproveRecord();

        List<WorkTaskPoolHistory> workTaskPoolHistoryList = workTaskPoolHistoryService.list(
                Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                        .eq(WorkTaskPoolHistory::getApplyNo,approveCondition.getApplyNo())
                        .eq(WorkTaskPoolHistory::getStageId,approveCondition.getStageId())
        );
        if (CollectionUtils.isNotEmpty(workTaskPoolHistoryList)) {
            for (WorkTaskPoolHistory workTaskPoolHistory : workTaskPoolHistoryList) {
                String remainDataStr = workTaskPoolHistory.getRemainData();
                if (StringUtils.isNotEmpty(remainDataStr)) {
                    JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                    if (remainJson.containsKey(AfsEnumUtil.key(AfsEnumUtil.key(RemainKeyEnum.RECORD)))) {
                        record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(),CaseApproveRecord.class);
                    }
                    recordList.add(record);
                }
            }
        }
        return IResponse.success(recordList);
    }

    @GetMapping("/queryUpApprove")
    @ApiOperation("资产变更已提交审批建议查询")
    public IResponse<List<CaseApproveRecord>> queryUpApprove(@ModelAttribute ApproveCondition approveCondition) {
        List<CaseApproveRecord> recordList = new ArrayList<>();
        CaseApproveRecord record = new CaseApproveRecord();

        List<WorkTaskPoolHistory> workTaskPoolHistoryList = workTaskPoolHistoryService.list(
                    Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                                .eq(WorkTaskPoolHistory::getApplyNo,approveCondition.getApplyNo())
                                .eq(WorkTaskPoolHistory::getStageId,approveCondition.getStageId())
        );
        if (CollectionUtils.isNotEmpty(workTaskPoolHistoryList)) {
            for (WorkTaskPoolHistory workTaskPoolHistory : workTaskPoolHistoryList) {
                String remainDataStr = workTaskPoolHistory.getRemainData();
                if (StringUtils.isNotEmpty(remainDataStr)) {
                    JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                    if (remainJson.containsKey(AfsEnumUtil.key(AfsEnumUtil.key(RemainKeyEnum.RECORD)))) {
                        record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(),CaseApproveRecord.class);
                    }
                    recordList.add(record);
                }
            }
        }
        return IResponse.success(recordList);
    }

    @GetMapping("/queryReturnApprove")
    @ApiOperation("上一岗退回后，查询原审批记录")
    public IResponse queryReturnApprove(@ModelAttribute ApproveCondition approveCondition) {
        CaseApproveRecord record = new CaseApproveRecord();

        WorkProcessScheduleInfo workProcessScheduleInfo = workProcessScheduleInfoService.getOne(Wrappers.<WorkProcessScheduleInfo>lambdaQuery()
                .eq(WorkProcessScheduleInfo::getId,approveCondition.getStageId()));

        List<WorkTaskPoolHistory> list = workTaskPoolHistoryService.list(Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                            .eq(WorkTaskPoolHistory::getApplyNo,approveCondition.getApplyNo())
                            .eq(WorkTaskPoolHistory::getStageId,approveCondition.getStageId())
                            .eq(WorkTaskPoolHistory::getTaskNodeId,workProcessScheduleInfo.getCurrentNodeId())
        );
        if (CollectionUtils.isNotEmpty(list)) {
            WorkTaskPoolHistory workTaskPoolHistory = list.get(0);
            String remainDataStr = workTaskPoolHistory.getRemainData();
            if (StringUtils.isNotEmpty(remainDataStr)) {
                JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                    record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(),CaseApproveRecord.class);
                }
            }
        }
        return IResponse.success(record);
    }

    @GetMapping("/queryApproveReason")
    @ApiOperation("查询组长提交复议意见")
    public IResponse queryApproveReason(@ModelAttribute ApproveCondition approveCondition) {

        WorkProcessScheduleInfo workProcessScheduleInfo = workProcessScheduleInfoService.getOne(Wrappers.<WorkProcessScheduleInfo>lambdaQuery()
                .eq(WorkProcessScheduleInfo::getId,approveCondition.getStageId()));
        if (ObjectUtils.isNotEmpty(workProcessScheduleInfo)) {
            List<WorkTaskPoolHistory> workTaskPoolHistoryList = workTaskPoolHistoryService.list(
                    Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                            .eq(WorkTaskPoolHistory::getApplyNo,approveCondition.getApplyNo())
                            .eq(WorkTaskPoolHistory::getStageId,approveCondition.getStageId())
                            .eq(WorkTaskPoolHistory::getTaskNodeId,workProcessScheduleInfo.getCurrentNodeId())
            );
            if (ObjectUtils.isNotEmpty(workTaskPoolHistoryList)) {
                WorkTaskPoolHistory workTaskPoolHistory = workTaskPoolHistoryList.get(0);
                CaseApproveRecord record = new CaseApproveRecord();
                String remainDataStr = workTaskPoolHistory.getRemainData();
                if (StringUtils.isNotBlank(remainDataStr)) {
                    JSONObject remainJson = JSONObject.parseObject(remainDataStr);
                    if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                        record = JSONObject.parseObject(remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(), CaseApproveRecord.class);
                    }
                }
                return IResponse.success(record);
            }
        }
        return IResponse.success("");
    }

    @PostMapping("/saveApprove")
    @ApiOperation("资产变更暂存")
    @Transactional
    public IResponse saveApprove(@RequestBody ApproveSubmitVO approveSubmitVO) {
        CaseApproveRecord caseApproveRecord = approveSubmitVO.getApproveRecord();
        if (Objects.nonNull(caseApproveRecord)) {
            WorkTaskPool workTaskPool = workTaskPoolService.getOne(
                    Wrappers.<WorkTaskPool>lambdaQuery()
                            .eq(WorkTaskPool::getApplyNo, caseApproveRecord.getApplyNo())
                            .eq(WorkTaskPool::getStageId, caseApproveRecord.getStageId())
            );
            // 暂存数据
            JSONObject jsonObject = new JSONObject();
            if (StringUtils.isNotBlank(workTaskPool.getRemainData())) {
                jsonObject = JSONObject.parseObject(workTaskPool.getRemainData());
            }
            jsonObject.put(AfsEnumUtil.key(RemainKeyEnum.RECORD), JSONObject.toJSON(caseApproveRecord));
            workTaskPool.setRemainData(jsonObject.toString());
            workTaskPoolService.updateById(workTaskPool);
        }
        return IResponse.success(approveSubmitVO);
    }

    @PostMapping("submitApprove")
    @ApiOperation("资产变更提交审批")
    public IResponse submitApprove(@RequestBody ApproveSubmitVO approveSubmitVO) {
        CaseApproveRecord caseApproveRecord = approveSubmitVO.getApproveRecord();
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(caseApproveRecord.getStageId());
        caseApproveRecord.setUseScene(UseSceneEnum.CHANGE_ASSETS.getValue());
        caseApproveRecord.setApproveType(ApproveTypeEnum.PROCESS.getValue());
        workflowService.submit(NormalTaskSubmitVO.builder().record(caseApproveRecord).workFlowInfo(info).build());
        return IResponse.success("提交成功");
    }

    /**
     * @description: 流程撤销
     * @author jiaqi.guo
     * @created 2020/7/28 20:23
     * @version 1.0
     */
    @PostMapping("/cancelFlow")
    public IResponse cancelFlow(@RequestBody WorkflowCancelVO cancelVO) {
        workflowService.cancelFlow(cancelVO.getStageId(), cancelVO.getMessage());
        return IResponse.success("操作成功");
    }
    /**
     * @description: 变更后信息维护
     * @author jiaqi.guo
     * @created 2020/8/11 11:09
     * @version 1.0
     */
    @PostMapping("/getChangeAssets/{applyNo}")
    public IResponse getChangeAssets(@PathVariable String applyNo) {
        CaseRedundantInfo redundantInfo= redundantInfoService.getOne(Wrappers.<CaseRedundantInfo>query().lambda()
                .eq(StringUtils.isNotBlank(applyNo),CaseRedundantInfo::getApplyNo,applyNo));

        List<ChangeAssetsVo> list = new ArrayList<>();
        //新旧数据对比展示
        ChangeAssetsVo changeAssetsVoBe = new ChangeAssetsVo();
        ChangeAssetsVo changeAssetsVoAf = new ChangeAssetsVo();
        if (ObjectUtils.isNotEmpty(redundantInfo)) {
            if (StringUtils.isNotEmpty(redundantInfo.getChangeAssetsRepeat())) {
                String jsonStr = redundantInfo.getChangeAssetsRepeat();
                JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                ChangeAssetsVo beforeJson = jsonObject.getJSONObject("beforeParameter").toJavaObject(ChangeAssetsVo.class);
                ChangeAssetsVo afterJson = jsonObject.getJSONObject("afterParameter").toJavaObject(ChangeAssetsVo.class);
                BeanUtils.copyProperties(beforeJson, changeAssetsVoBe);
                BeanUtils.copyProperties(afterJson, changeAssetsVoAf);
                list.add(changeAssetsVoBe);
                list.add(changeAssetsVoAf);
            }
        }
        List<ChangeAssetsViewVo> changeList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            Field[] field = list.get(0).getClass().getDeclaredFields();
            for (int i = 0; i < field.length; i++) {
                Field f = field[i];
                Object valueBefor= getFieldValueByName(f.getName(),list.get(0));
                Object valueAfter= getFieldValueByName(f.getName(),list.get(1));
                ChangeAssetsViewVo  viewVo= new ChangeAssetsViewVo();
                viewVo.setKeyName(f.getName());
                if(ObjectUtils.isNotEmpty(valueBefor)){
                    viewVo.setBeforParam(valueBefor.toString());
                }
                if(ObjectUtils.isNotEmpty(valueAfter)){
                    viewVo.setAfterParam(valueAfter.toString());
                }
                changeList.add(viewVo);
            }
        }
        return IResponse.success(changeList);
    }

    /**
     * 根据属性名获取属性值
     * @param fieldName
     * @param o
     * @return
     */
    private Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }

    }

    /**
     * @Description 资产变更退回保存留言
     * @Date 2020/08/14 14:22
     */
    @PostMapping("/saveRemind")
    public IResponse saveRemind(@RequestParam("remind")String remindJsonStr,
                                  @RequestParam("record")String recordJsonStr,
                                  @RequestParam("remindOprType")String remindOprType){
        AfsUser user = SecurityUtils.getUser();

        // 审批日志参数
        CaseApproveRecord record = JSONObject.parseObject(recordJsonStr,CaseApproveRecord.class);

        // 1.留言记录信息
        CaseRemindDetail remindDetail = JSONObject.parseObject(remindJsonStr,CaseRemindDetail.class);
        remindDetail.setDisposeUser(user.getUserRealName());
        remindDetail.setDisposeUserId(user.getId().toString());
        remindDetail.setStatus(CancelStatusEnum.EFFECTIVE.getCode());
        remindDetail.setDisposeTime(new Date());
        remindDetail.setUseScene(record.getUseScene());
        remindDetail.setOperationType(remindOprType);
        // 内部留言默认 经销商不可见
        if(RemindTypeEnum.INNER.getValue().equals(remindDetail.getRemindType())){
            remindDetail.setRemindPowers(RemindPowerEnum.UN_VISIBLE.getValue());
        }else{
            remindDetail.setRemindPowers(RemindPowerEnum.VISIBLE.getValue());
        }

        // 公共日志参数
        record.setApplyNo(remindDetail.getApplyNo());
        record.setUseScene(UseSceneEnum.CHANGE_ASSETS.getValue());
        record.setDisposeStaff(user.getUserRealName());
        record.setApproveEndTime(new Date());

        // 2.留言日志
        CaseApproveRecord remindRecord = new CaseApproveRecord();
        BeanUtil.copyProperties(record,remindRecord);

        remindRecord.setApproveType(ApproveTypeEnum.REMIND.getValue());
        remindRecord.setApproveSuggestName(RemindTypeEnum.getNameByValue(remindDetail.getRemindType()));
        remindRecord.setApproveSuggest(remindDetail.getRemindType());
        remindRecord.setApproveReason(remindDetail.getRemindReason());
        remindRecord.setApproveRemark(remindDetail.getRemindContent());


        if(RemindOperateTypeEnum.REJECT.getValue().equals(remindOprType)){
            WorkTaskPool taskPool = workTaskPoolService.getOne(
                    Wrappers.<WorkTaskPool>lambdaQuery().eq(WorkTaskPool::getStageId, record.getStageId()));

            record.setApproveStartTime(taskPool.getStartTime());

            remindRecord.setDisposeNode(taskPool.getTaskNodeId());
            remindRecord.setDisposeNodeName(taskPool.getTaskNodeName());
            remindRecord.setApproveStartTime(taskPool.getStartTime());

            // 3.流程日志
            CaseApproveRecord approveRecord = new CaseApproveRecord();
            BeanUtil.copyProperties(record,approveRecord);
            approveRecord.setApproveType(ApproveTypeEnum.REMIND.getValue());
            approveRecord.setApproveSuggestName(RemindOperateTypeEnum.getNameByValue(remindOprType));
            approveRecord.setApproveSuggest(remindOprType);
            approveRecord.setApproveRemark(record.getApproveRemark());
            approveRecord.setApproveStartTime(approveRecord.getApproveEndTime());
            approveRecord.setApproveReason(remindDetail.getRemindReason());
            approveRecord.setApproveMessage(remindDetail.getRemindContent());

            if(RemindOperateTypeEnum.REJECT.getValue().equals(remindOprType)){
                approveRecord.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.SEND_BACK));
                approveRecord.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.SEND_BACK));
                workflowService.submit(NormalTaskSubmitVO.builder().record(approveRecord).build());
            }
        }else if(RemindPowerEnum.VISIBLE.getValue().equals(remindDetail.getRemindPowers())){
            // 通知进件系统
            approveInformInfoService.submitLeaveMessageForAssets(remindDetail);
        }

        caseApproveRecordService.save(remindRecord);
        remindService.save(remindDetail);
        return IResponse.success("ok");
    }
}